from mootdx.quotes import Quotes
from mootdx.reader import Reader
from mootdx.affair import Affair
from mootdx import consts
import pandas as pd
import pendulum
from qmt_tool.confile_tool import get_conf_tongdaxin_file
from mootdx.utils import holiday
from mootdx.consts import KLINE_DAILY
from datetime import datetime, timedelta
from  qmt_tool.trade_time_tool import check_is_trade_date
class tdxmoo_data:
    def __init__(self):
        self.client=Quotes.factory(market='std')
        tdxdict=get_conf_tongdaxin_file()
        self.reader = Reader.factory(market='std', tdxdir=tdxdict['通达信目录'])
    def get_tick_data_oneday(self, stock='600031',date=pendulum.today().strftime('%Y%m%d')):
        # 获取一整天 3s 一次的 tick数据
        sotck=self.adjust_stock(stock)
        # self.client=Quotes.factory(market='std')
        df = self.client.transactions(symbol=sotck,start=0,date=date)
        return df

    def get_tick_data_today(self, stock='600031',offset=4000 ):
        # 获取一整天 3s 一次的 tick数据
        sotck = self.adjust_stock(stock)
        # self.client = Quotes.factory(market='std')
        df = self.client.transaction(symbol=sotck, start=0, offset=offset)
        return df

    def get_jhjj_data_oneday(self, stock='000561',date=pendulum.today().strftime('%Y%m%d') ):

        # sotck = self.adjust_stock(stock)
        # 这个方式，会取竞价从9.25 到9.33分钟， 每3s 一次的成交量

        df = self.client.transactions(symbol=stock, start=2000, offset=3000, date=date)
        # df = self.client.minutes(symbol=sotck,date=date)
        if len(df)>0:
            if df.head(1)['time'].values[0]=='09:25':
                tmp_df=df.head(1).copy()
                tmp_df['symbol']=stock
                tmp_df['trade_date']=date
                return tmp_df
            else:
                tmp_df=pd.DataFrame()
                return tmp_df
        else:
            df=pd.DataFrame()
            return df

    def date_iteration_datetime(self,start_date, end_date):
        """
        使用 datetime 库进行日期迭代
        :param start_date: 起始日期，格式为 'YYYY-MM-DD'
        :param end_date: 结束日期，格式为 'YYYY-MM-DD'
        :return: 日期迭代器
        """
        start = datetime.strptime(start_date, '%Y%m%d')
        end = datetime.strptime(end_date, '%Y%m%d')
        current = start
        while current <= end:
            yield current.strftime('%Y%m%d')
            current += timedelta(days=1)
    def get_jhjj_all_stock(self,start_date='20250401',end_date='20250526'):
        #以start_date 为开始，end_date 为结束，循环获取竞价数据
        df=pd.DataFrame()
        stock_list=self.get_define_block_from_tdxfile(block_name='主创备选池')
        df =pd.DataFrame()
        for symbol in stock_list:
            # print(symbol)
            for date in self.date_iteration_datetime(start_date, end_date):

                if check_is_trade_date(date):
                    tmp_df=self.get_jhjj_data_oneday(stock=symbol,date=date)
                    if tmp_df.empty:
                        continue
                    else:
                        df=pd.concat([df,tmp_df])

        return df

    def get_first_minute_data_oneday(self,stock='600031',date=pendulum.today().strftime('%Y%m%d')):
        stock=stock
        df = self.client.minutes(symbol=stock, date=date)
        if not df.empty > 0:
                tmp_df = df.head(1).copy()
                tmp_df.loc[:,'symbol'] = stock
                tmp_df.loc[:,'trade_date'] = date
                return tmp_df

        else:
            df = pd.DataFrame()
            return df

    def get_first_minute_all_stock(self,start_date='20250401',end_date='20250526'):
        #以start_date 为开始，end_date 为结束，循环开盘第一分钟数据
        df=pd.DataFrame()
        stock_list=self.get_define_block_from_tdxfile(block_name='主创备选池')
        df =pd.DataFrame()
        for symbol in stock_list:
            for date in self.date_iteration_datetime(start_date, end_date):
                if check_is_trade_date(date):
                    tmp_df = self.get_first_minute_data_oneday(stock=symbol, date=date)
                    if tmp_df.empty:
                        continue

                    else:

                        df=pd.concat([df,tmp_df])

        return df
    def get_caiwu_data(self):
        #要是用
        # affair = Affair.factory(market='std', tdxdir=r'C:\new_tdx')
        pass

    def get_kline_day2(self,stock='600531',start='2023-01-01',end='2050-01-01',adjust='qfq'):

        df = self.client.ohlc(symbol=stock, adjust='qfq', begin=start,end=end)
        data = pd.DataFrame()
        data['date'] = df['date']
        data[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']]
        data['成交额'] = df['amount']
        data['涨跌幅'] = df['close'].pct_change(fill_method='pad') * 100
        data['涨跌额'] = data['close'] - data['open']
        data['振幅'] = (data['high'] - data['low']) / data['low'] * 100
        data.dropna(inplace=True)
        return df
    def get_kline_day(self, stock='600031', frequncy='day', count=200):
        df=self.client.bars(symbol=stock,adjust='qfq', frequency=frequncy, count=count)
        data = pd.DataFrame()
        data['date'] = df['datetime'].str[0:10]
        data[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']]
        data['成交额'] = df['amount']
        data['涨跌幅'] =df['close'].pct_change(fill_method='pad') * 100
        data['涨跌额'] = data['close'] - data['open']
        data['振幅'] = (data['high'] - data['low']) / data['low'] * 100
        data.dropna(inplace=True)
        return data

    def get_index_kline_day(self, index='399001', frequncy=9, count=200):
        df=self.client.index(symbol=index)
        data = pd.DataFrame()
        data['date'] = df['datetime'].str[0:10]
        data[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']]
        data['成交额'] = df['amount']
        data['涨跌幅'] = df['close'].pct_change(fill_method='pad') * 100
        data['涨跌额'] = data['close'] - data['open']
        data['振幅'] = (data['high'] - data['low']) / data['low'] * 100
        data['上涨家数']=df['up_count']
        data['下跌家数']=df['down_count']
        data.dropna(inplace=True)
        return data

    def get_index_first_minute_kline_day(self, index='399001', frequncy=8, count=200):
       # 这是1分钟数据，还没改完，不好取1分钟
        df=self.client.index(symbol=index,  frequency=8, count=count)
        data = pd.DataFrame()
        data['date'] = df['datetime'].str[0:10]
        data[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']]
        data['成交额'] = df['amount']
        data['涨跌幅'] = df['close'].pct_change(fill_method='pad') * 100
        data['涨跌额'] = data['close'] - data['open']
        data['振幅'] = (data['high'] - data['low']) / data['low'] * 100
        data['上涨家数']=df['up_count']
        data['下跌家数']=df['down_count']
        data.dropna(inplace=True)
        return data


    def get_zhangdiejiashu(self,index='880005'):
        #涨停家数
        df=self.client.index(symbol=index)
        data = pd.DataFrame()
        data['trade_date'] = df['datetime'].str[0:10]
        data[['下跌', '总数', '横盘', '上涨', '成交量',  '成交额', '涨幅3内', '跌幅3内']] = df[['open', 'high', 'low', 'close', 'volume','amount','up_count','down_count']]
        data.dropna(inplace=True)
        return data

    def get_zuorizhangting(self,index='880863'):
        df=self.client.index(symbol=index)
        data = pd.DataFrame()
        data['trade_date'] = df['datetime'].str[0:10]
        data[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']]
        data['成交额'] = df['amount']
        data['涨跌幅'] = df['close'].pct_change(fill_method='pad') * 100
        data['涨跌额'] = data['close'] - data['open']
        data['振幅'] = (data['high'] - data['low']) / data['low'] * 100
        data.dropna(inplace=True)
        return data


    def get_kline_min(self, stock='600031', frequncy='15m',date=pendulum.today().strftime('%Y%m%d')):
        # 参数可以是 1m,5m,15m,30m,  #   失败娶不到值
        data_dict = {'1': '1m', '5': '5m', '15':'15m', '30': '30m', '60': '1h','D':'day'}
        period=data_dict[frequncy]
        symbol=self.adjust_stock(stock)
        # self.client=Quotes.factory(market='std')
        df = self.client.bars(symbol=symbol,date=date, frequency='15m' )
        data = pd.DataFrame()
        data['date'] = df['datetime'].str[0:10]
        data[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']]
        data['成交额'] = df['amount']
        data['涨跌幅'] = df['close'].pct_change(fill_method='pad') * 100
        data['涨跌额'] = data['close'] - data['open']
        data['振幅'] = (data['high'] - data['low']) / data['low'] * 100
        return df
    def get_tdx_fenshi240(self, stock='600031',date=pendulum.today().strftime('%Y%m%d')):
        #就是计算的通达信 ，分时图，每分钟的那个价格线， 也是1分钟的  收盘价 早晨的数据是从9.31开始的
        try:
            wudang=self.get_stock_5dang_pankou(stock=stock,)
            preclose=wudang['last_close'].values[0]
            df = self.client.minutes(symbol=stock, date=date)
            if len(df)==0:
                date=pendulum.today().subtract(days=1).strftime('%Y%m%d')
                df = self.client.minutes(symbol=stock, date=date)
            df['涨跌幅'] = (df['price']-preclose)/preclose*100
        except Exception as e:
             print(e)
             df=pd.DataFrame()
             df['date']=None
             df['price']=None
             df['涨跌幅']=None
             df['volume']=None
             df['vol']=None
        return df
    def select_data_type(self, stock='600031'):
        '''
        选择数据类型
        '''
        if stock[:3] in ['110', '113', '123', '127', '128', '111', '118'] or stock[:2] in ['11', '12']:
            return 'bond'
        elif stock[:3] in ['510', '511', '512', '513', '514', '515', '516', '517', '518', '588', '159', '501',
                           '164'] or stock[:2] in ['16']:
            return 'fund'
        else:
            return 'stock'

    def adjust_stock(self, stock='600031.SH'):
        '''
        调整代码
        '''
        if stock[-2:] == 'SH' or stock[-2:] == 'SZ' or stock[-2:] == 'sh' or stock[-2:] == 'sz':
            stock = stock.upper()
        else:
            if stock[:3] in ['600', '601', '603', '688', '510', '511',
                             '512', '513', '515', '113', '110', '118', '501'] or stock[:2] in ['11']:
                stock = stock + '.SH'
            else:
                stock = stock + '.SZ'
        return stock

    def rename_stock_type_1(self, stock='600031'):
        '''
        将股票类型格式化
        stock证券代码
        1上海
        0深圳
        '''
        if stock[:3] in ['600', '601', '603', '688', '510', '511',
                         '512', '513', '515', '113', '110', '118', '501'] or stock[:2] in ['11']:
            marker = 1
        else:
            marker = 0
        return marker, stock

    def rename_stock_type(self, stock='600031'):
        '''
        将股票类型格式化
        stock证券代码
        1上海
        0深圳
        '''
        if stock[:3] in ['600', '601', '603', '688', '510', '511',
                         '512', '513', '515', '113', '110', '118', '501'] or stock[:2] in ['11']:
            marker = 1
        else:
            marker = 0
        result = [(marker, stock)]
        return result

    def marker_type(self, stock='600031'):
        '''
        判断市场类型
        '''
        if stock[:3] in ['600', '601', '603', '688', '510', '511',
                         '512', '513', '515', '113', '110', '118', '501'] or stock[:2] in ['11']:
            marker = 1
        else:
            marker = 0
        return marker

    def get_security_quotes_none(self, stock='600031'):
        pass

    def get_stock_5dang_pankou(self, stock='600031'):
        df=self.client.quotes(symbol=stock)
        df = df[['code', 'open', 'high', 'low', 'price', 'volume', 'cur_vol', 'amount', 's_vol', 'b_vol', 'last_close',
                 'servertime', 'bid1', 'ask1', 'bid2', 'ask2']]
        return df

    def get_stock_5dang_pankou_many(self, stock=['600031','300331']):
        df=self.client.quotes(symbol=stock)
        return df







    def marker_params(self, stock='600031'):
        if stock[:3] in ['600', '601', '603', '688', '510', '511',
                         '512', '513', '515', '113', '110', '118', '501'] or stock[:2] in ['11']:
            marker = 1
        else:
            marker = 0
        return marker


    def get_daily_from_tdxfile(self, symbol='600031', date='20230729'):
        # 读取日线数据
        df = self.reader.daily(symbol=symbol)
        # df = df.set_index('date', drop=False)

        return df

    def get_minute_data_from_tdxfile(self, symbol='600031'):
        # 读取1分钟数据
            self.reader.minute(symbol=symbol,)

    def get_blocks_from_tdxfile(self,block_name):
        self.reader.block(symbol=block_name, group=True)

    # def get_stock_hist_data_tdx(self, stock='600031', start_date='20210101', end_date='20500101'):
    #     result= self.client.get_k_data(code=stock, start=start_date, end=end_date)
    def get_define_block_from_tdxfile(self, block_name=''):
        # 默认扁平格式
        # self.reader.block_new()
        # 分组格式
        result=self.reader.block_new(name=block_name,group=True)
        return result

    def write_symbol_2tdx_block(self, block_name, symbol_list):

        self.reader.block_new(name=block_name, symbol=symbol_list)



if __name__ == '__main__':
    tdx_data=tdxmoo_data()
    # print(tdx_data.get_kline_min(stock='600031', frequncy='5',date='20240729'))
    # print(tdx_data.get_index_kline_day(index='399001', frequncy=KLINE_DAILY, count=200))
    # print(tdx_data.get_stock_5dang_pankou(stock='300331' ))
    # print(tdx_data.get_conv_bond_define_second(stock='123035'))
    # print(tdx_data.get_daily_from_tdxfile(symbol='300331'))

    print(tdx_data.get_zuorizhangting())

